Skip to content

Instantly share code, notes, and snippets.

@sveisvei
Created August 16, 2010 23:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sveisvei/528000 to your computer and use it in GitHub Desktop.
Save sveisvei/528000 to your computer and use it in GitHub Desktop.
io = require 'socket.io'
fs = require 'fs'
sys = require 'sys'
http = require 'http'
path = require 'path'
colors = require 'colors'
events = require 'events'
connect = require 'connect'
cs = require './coffee-script/lib/coffee-script'
# Shortcuts
ins = sys.inspect
# Global cache
cache = {}
class Watcher extends events.EventEmitter
constructor: (dir, name) ->
@log = () ->
args = Array.prototype.slice.call arguments
now = new Date()
console.log "#{ @APP.red }
[#{ (new Date().toGMTString()).grey }]
#{ @NAME.green } -
=> #{ (args.splice(0,1)) }"
console.log "#{ ((args.join ' - ').grey) }" if args.length
@dir = dir
@NAME = name ||'Log'
@APP = "[WATCHER]"
@rules = {
files : [
{
type: 'js'
active: true
action: (file, next) =>
## do something and send a file
@log 'js action'
next(file)
},
{
type: 'coffee'
active: true
action: (file, next) =>
@log 'coffee action'
## Read filecontents
fs.readFile file.fullpath, (err, code) =>
@log "compiling..."
compiled = cs.compile(code)
@log compiled
next(file)
},
{
type: 'html'
active: true
action: (file, next) =>
## compile
@log 'html action'
next(file)
},
{
type: 'css'
active: true
action: (file, next) =>
## compile
next(file)
},
{
type: 'scss'
active: false
action: (file, next) =>
## start compass on this one
next(file)
}
]
}
Watcher::clearCache = (cb) ->
cache = {}
cb() if cb?
return this
Watcher::createServer = (port, ip) ->
@log "Starting websocket server #{ip}:#{port}"
@server = connect.createServer(
connect.logger(),
connect.staticProvider(@dir)
)
# upgrade server
@socket = io.listen @server
@server.listen port, ip
#@clients = []
@socket.on 'connection', (client) =>
@log "Client ( #{client.sessionId} ) connected"
client.send '{"message":"connected"}'
client.on 'message', (message) =>
jmessage = JSON.parse(message)
@log "Client ( #{client.sessionId} ) message to server: #{message}"
client.send JSON.stringify({"message": "ok. #{message}"}) if !jmessage.message == 'ok'
client.on 'disconnect', () =>
@log "Client ( #{client.sessionId} ) dropped"
return @server
Watcher::stop = () ->
@log 'Stopping... (Nothing happens)'
return @
# Crawl all folders
Watcher::start = (dir) ->
self = @
@interval ?= 500
# If watching length, unwatch all files?
@watching = []
dir ?= @dir ?= process.cwd()
inRules = (filename) ->
# Check for fileending in rules
fileending = filename.substring(filename.lastIndexOf('.') + 1, filename.length)
#@log self.rules
for ruleset in self.rules?.files
if ruleset.active == true and ruleset.type == fileending
return ruleset
return false
crawl = (dir) =>
fs.readdir dir, (err, files) =>
throw err if err?
files = path.normalizeArray files
files.forEach (file) =>
fullpath = dir + '/' + file
fs.stat fullpath, (err, stats) =>
throw err if err?
rulesObj = inRules(file)
if stats.isFile() and rulesObj != false
fileobj = {
fullpath: fullpath
filename: file
}
@watching.push(fileobj) if duplicate?
fs.watchFile fullpath, {interval: @interval}, (curr, next) =>
if (curr.mtime > next.mtime)
rulesObj.action fileobj, (fileObj) =>
@emit 'change', fileObj
else if stats.isDirectory()
if !(file.substring(0, 1) == '.')
crawl fullpath
crawl(dir)
return @
module.exports = Watcher
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment