Beispiel #1
1
func main() {
	sourceDir, destDir, destSubfolder, fileType, mode := "", "", "", "", ""

	log.SetPrefix(fmt.Sprintf("cache-monitor (PID %d) ", os.Getpid()))

	var debug bool

	flag.StringVar(&sourceDir, "sourcedir", "", "The source directory where this cache-monitor should pull files from. The cache manager automatically watches files in base/, mobile/, and desktop/, calling the handler for each modified file.")
	flag.StringVar(&destDir, "destdir", "", "The cache directory where this cache-monitor should place files in. If this directory does not exist, it is created. Subfolders for each different layout are generated automatically.")
	flag.StringVar(&destSubfolder, "destsubfolder", "", "Do you want the files to end up in a subdirectory? This is different from changing the destdir in that the subfolder is applied to the path after the layout. E.g. setting the subfolder to 'events' would make the files end up in $sourcedir/$layout/$events/$file for each layout.")
	flag.StringVar(&fileType, "filetype", "", "What filetype is this cache-monitor monitoring? This generally, but not always, corresponds to the file extension. For example, 'js', 'css', 'img', and 'tmpl' are all valid types.")
	flag.StringVar(&mode, "mode", "sync", "What mode should the monitor run in? Valid options include:\n\tsync: Runs once, performing a one-way sync of all files.\n\tdeamon: Runs in the background, updating files as they are changed. Currently only supported on Linux.")
	flag.BoolVar(&debug, "debug", false, "Run in debug mode? Outputs a lot more garbage.")
	flag.Parse()

	if debug {
		dlog = log.New(os.Stderr, "DEBUG: ", log.Ltime|log.Lshortfile)
	} else {
		nul, err := os.OpenFile(os.DevNull, os.O_WRONLY, 0)
		if err != nil {
			log.Fatal("Could not open null device? Wtf?")
		}
		dlog = log.New(nul, "", 0)
	}

	if mode == "deamon" {
		dlog.Println("Warning: Deamon mode is still beta. Currently it only works on linux systems with inotify support.")
	}

	var v Visitor
	v.source = new(Path)
	v.dest = new(Path)
	v.source.root = sourceDir
	v.dest.root = destDir
	v.dest.subfolder = destSubfolder
	v.fileType = fileType

	var err error

	if mode == "deamon" {
		v.deamon = true
		v.watcher, err = inotify.NewWatcher()
		if err != nil {
			log.Fatal("Error creating inotify instance; deamon mode cannot possibly work.")
		}
	}

	if !osutil.FileExists(sourceDir) {
		dlog.Printf("Warning: Given source directory of %s does not exist, exiting...", sourceDir)
		os.Exit(0)
	}
	filepath.Walk(sourceDir, filepath.WalkFunc(func(pat string, fi os.FileInfo, err error) error { return v.Visit(pat, fi, err) }))

	if v.deamon {
		v.InotifyLoop()
	}
}
Beispiel #2
0
func NewWatcher() (*Watcher, error) {
	watch, err := inotify.NewWatcher()
	if err != nil {
		return nil, err
	}
	w := &Watcher{watch, map[string]bool{}}
	return w, nil
}
Beispiel #3
0
// WatchTemplates is responsible for template caching
// and live reloading (if live-templates option is activated)
func WatchTemplates(ctx *gwp_context.Context) {
	// we're tracking live changes to template files
	if ctx.App.LiveTemplates == true {
		watcher, err := inotify.NewWatcher()
		if err != nil {
			ctx.ErrorMsg <- errors.New("Could not create inotify watcher: " + err.Error())
			return
		}
		defer watcher.Close()

		WatchList = make(map[string]bool)

		for {
			select {
			case ev := <-watcher.Event:
				// cached file was modified
				if ctx.Templates[ev.Name] != nil {
					delete(ctx.Templates, ev.Name)
				}
				if WatchList[ev.Name] == true {
					watcher.RemoveWatch(ev.Name)
					WatchList[ev.Name] = false
				}

			case ev := <-watcher.Error:
				// this probably means something has gone terribly wrong, so we exit
				ctx.ErrorMsg <- ev
				return

			case ev := <-ctx.LiveTplMsg:
				ctx.Templates[ev.Name] = ev.Tpl

				// check if we're already watching this file name
				if WatchList[ev.Name] == true {
					watcher.RemoveWatch(ev.Name)
					watcher.AddWatch(ev.Name, inotify.IN_MODIFY)
				} else {
					watcher.AddWatch(ev.Name, inotify.IN_MODIFY)
					WatchList[ev.Name] = true
				}
			}
		}
		// we're just preloading/caching templates. No runtime updates are possible.
	} else {

		for {
			ev := <-ctx.LiveTplMsg
			ctx.Templates[ev.Name] = ev.Tpl
		}
	}

}
Beispiel #4
0
func (cm *CacheMonitor) Deamon(errors chan<- error) {
	watcher, err := inotify.NewWatcher()
	if err != nil {
		errors <- err
		return
	}
	err = cm.daemonInit(watcher, cm.source.Name())
	for {
		select {
		case ev := <-watcher.Event:
			cm.daemonEvent(ev)
		case err := <-watcher.Error:
			errors <- err
		}
	}
}
Beispiel #5
0
/* Recursively listens for changes to files within the 'path', and passes any
 * discovered changes to 'out'. Returns an error if any are encountered, or
 * returns nil if 'path' is deleted or Stop() is called */
func (l *Listener) Listen(out chan<- *ListenEvent) error {
	watcher, err := inotify.NewWatcher()
	if err != nil {
		return err
	}
	defer watcher.Close()

	info, err := os.Stat(l.path)
	if err != nil {
		return err
	}

	if info.IsDir() {
		tree, err := NewdirTree(l.path, watcher, out)
		if err != nil {
			return err
		}
		log.Print(tree.String())

	RECVDIR:
		for {
			select {
			case ev := <-watcher.Event:
				err = tree.Signal(ev)
				if err != nil {
					break RECVDIR
				}
			case err = <-watcher.Error:
				break RECVDIR
			case <-l.abort:
				log.Println("Listen: Abort ", l.path)
				break RECVDIR
			}
		}
	} else if info.Mode()&os.ModeType == 0 { /* regular file */
		watcher.AddWatch(l.path, file_watch_mode)

	RECVFILE:
		for {
			select {
			case ev := <-watcher.Event:
				log.Println("event:", ev)
				c := uint32(ev.Mask)
				sendme := new(ListenEvent)
				sendme.Path = ev.Name
				if c&(inotify.IN_DELETE_SELF|inotify.IN_MOVE_SELF) != 0 {
					sendme.Code = REMOVED
				} else if c&inotify.IN_MODIFY != 0 {
					sendme.Code = MODIFIED
				} else {
					log.Println("Listener: Unknown file event code: ", c)
					continue
				}
				out <- sendme
				if sendme.Code == REMOVED {
					log.Println(fmt.Sprintf("Listener: Watched path %s was moved/deleted!", l.path))
					break RECVFILE
				}
			case err = <-watcher.Error:
				break RECVFILE
			case <-l.abort:
				log.Println("Listen: Abort ", l.path)
				break RECVFILE
			}
		}
	} else {
		err = errors.New(fmt.Sprintf("Listener: Path %s is neither a directory nor a regular file", l.path))
	}
	close(out)
	return err
}
Beispiel #6
0
func main() {

	runtime.GOMAXPROCS(runtime.NumCPU())

	var version = "1.0.a"

	var ff = flag.String("fileList", "/", "File list. : seperated")
	var hf = flag.Int("httpPort", 8080, "HTTP Port")
	var sf = flag.Bool("serveLocalhost", false, "Serve as localhost")
	var tf = flag.Int("tcpPort", 0, "TCP port")
	var df = flag.Int("tcpDelim", 10, "TCP message delimiter")
	var wf = flag.String("watchList", "./", "Watch list. : seperated")
	var _ = flag.String("version", version, "Version")

	var fileList string
	var serveLocalhost bool
	var httpPort int
	var tcpPort int
	var tcpDelimiter string
	var err error

	flag.Parse()

	watchList = *wf
	fileList = *ff
	serveLocalhost = *sf
	httpPort = *hf
	tcpPort = *tf
	tcpDelimiter = EncChar(*df)

	myLog.Printf("jsonSpew %v\n", version)

	if watcher, err = inotify.NewWatcher(); err != nil {
		myLog.Fatalln(err)
	}

	for _, f := range strings.Split(fileList, ":") {
		http.HandleFunc(f, FileHandler)
		myLog.Printf("Registered %v\n", f)
	}

	for _, f := range strings.Split(watchList, ":") {
		if err := watcher.AddWatch(f, inotify.IN_CLOSE); err != nil {
			myLog.Println(err)
		}
		myLog.Printf("Watching:%v", f)
	}

	go channelSelect()

	http.Handle("/websocket", websocketHandler)

	hostname, _ := os.Hostname()
	host, _ := net.LookupHost(hostname)

	if serveLocalhost {
		host = append(host, "127.0.0.1")
	}

	if tcpPort != 0 {
		myLog.Printf("Serving tcp on %v %v", host, tcpPort)
		go ServeTCPChannel(fmt.Sprintf("%v:%v", host, tcpPort), tcpDelimiter, tcp)
	}

	myLog.Printf("Serving http on %v:%v\n", host, httpPort)
	if err := http.ListenAndServe(fmt.Sprintf("%v:%v", host, httpPort), nil); err != nil {
		panic(err)
	}

}