Beispiel #1
0
func (this *Watcher) handlecb(v *triggered, ev *fsnotify.FileEvent) {

	if !v.canrun() {
		return
	}
	defer v.setLastUpdate()

	// in windows some events are sent 3 times
	c := time.Tick(g_cooldown)
	<-c

	var t EvType
	// execute
	if ev.IsModify() {
		t = C_Modify
	} else if ev.IsCreate() {
		t = C_Create
	} else if ev.IsDelete() {
		t = C_Delete
	} else if ev.IsRename() {
		t = C_Rename
	} else if ev.IsAttrib() {
		t = C_Attrib
	} else {
		fmt.Fprintln(os.Stderr, "unknown event")
		return
	}

	this.cb(&WatchEvent{
		Type:  t,
		Fpath: ev.Name,
	})

}
Beispiel #2
0
func (p *postManager) processPostEvent(ev *fsnotify.FileEvent) {

	ext := strings.ToLower(filepath.Ext(ev.Name))
	switch ext {
	case p.brog.Config.PostFileExt:
	case ".md":
	case ".markdown":
	case ".mkd":
	default:
		p.brog.Debug("Posts ignore files in '%s': %s", ext, ev.Name)
		return
	}

	if ev.IsCreate() {
		p.processPostCreate(ev)
		return
	}

	if ev.IsModify() {
		p.processPostModify(ev)
		return
	}

	if ev.IsRename() {
		p.processPostRename(ev)
		return
	}

	if ev.IsDelete() {
		p.processPostDelete(ev)
		return
	}

	p.brog.Err("FileEvent '%s' is not recognized", ev.String())
}
Beispiel #3
0
func (fw *InotifyFileWatcher) ChangeEvents(t tomb.Tomb, fi os.FileInfo) chan bool {
	w, err := fsnotify.NewWatcher()
	if err != nil {
		panic(err)
	}
	err = w.Watch(fw.Filename)
	if err != nil {
		panic(err)
	}

	ch := make(chan bool)

	fw.Size = fi.Size()

	go func() {
		defer w.Close()
		defer w.RemoveWatch(fw.Filename)
		defer close(ch)

		for {
			prevSize := fw.Size

			var evt *fsnotify.FileEvent

			select {
			case evt = <-w.Event:
			case <-t.Dying():
				return
			}

			switch {
			case evt.IsDelete():
				fallthrough

			case evt.IsRename():
				return

			case evt.IsModify():
				fi, err := os.Stat(fw.Filename)
				if err != nil {
					// XXX: no panic here
					panic(err)
				}
				fw.Size = fi.Size()

				if prevSize > 0 && prevSize > fw.Size {
					return
				}

				// send only if channel is empty.
				select {
				case ch <- true:
				default:
				}
			}
		}
	}()

	return ch
}
Beispiel #4
0
func handleChange(channel *amqp.Channel, ev *fsnotify.FileEvent) error {
	// check to see if the file is locked. If it is then break
	path, _ := filepath.Rel(rootDir, ev.Name)
	if FileIsLocked(path) {
		return nil
	}
	log.Printf("PUBLISHER: publishing %dB path (%q)", len(path), path)

	var change = &Change{
		IsCreate: ev.IsCreate(),
		IsDelete: ev.IsDelete(),
		IsMod:    ev.IsModify(),
		IsMove:   ev.IsRename(),
		ModDate:  time.Now().UTC(),
		Path:     path,
		Source:   hostname,
		Checksum: Checksum(ev.Name),
	}

	msg, err := json.Marshal(change)
	if err != nil {
		log.Fatalf("ERROR marshaling msg %s", change)
	}

	if err := channel.Publish(
		"changes", // publish to an exchange
		"",        // routing to 0 or more queues
		false,     // mandatory
		false,     // immediate
		amqp.Publishing{
			Headers:         amqp.Table{},
			ContentType:     "application/json",
			ContentEncoding: "",
			Body:            msg,
			DeliveryMode:    amqp.Transient, // 1=non-persistent, 2=persistent
			Priority:        0,              // 0-9
			// a bunch of application/implementation-specific fields
			/*

				ContentType     string    // MIME content type
				ContentEncoding string    // MIME content encoding
				DeliveryMode    uint8     // Transient (0 or 1) or Persistent (2)
				Priority        uint8     // 0 to 9
				CorrelationId   string    // correlation identifier
				ReplyTo         string    // address to to reply to (ex: RPC)
				Expiration      string    // message expiration spec
				MessageId       string    // message identifier
				Timestamp       time.Time // message timestamp
				Type            string    // message type name
				UserId          string    // creating user id - ex: "guest"
				AppId           string    // creating application id
			*/
		},
	); err != nil {
		log.Fatalf("Exchange Publish: %s", err)
		panic(err)
	}

	return nil
}
Beispiel #5
0
func (t *templateManager) processTemplateEvent(ev *fsnotify.FileEvent) {
	ext := strings.ToLower(filepath.Ext(ev.Name))
	switch ext {
	case ".gohtml":
	case ".tmpl":
	default:
		t.brog.Debug("Templates ignore files in '%s': %s", ext, ev.Name)
		return
	}

	if ev.IsCreate() {
		// Nothing to do, all usefull templates files MUST exist at this
		// time or brog would not have started.
		return
	}

	if ev.IsModify() {
		t.processTemplateModify(ev)
		return
	}

	if ev.IsRename() || ev.IsDelete() {
		t.processTemplateDelete(ev)
		return
	}

	t.brog.Err("FileEvent '%s' is not recognized", ev.String())
}
Beispiel #6
0
func processSubdir(watcher *fsnotify.Watcher, ev *fsnotify.FileEvent) {
	if ev.IsModify() {
		return
	}
	if ev.IsDelete() {
		log.Println("remove watch", ev.Name)
		// FIXME: what to do with err?
		watcher.RemoveWatch(ev.Name)
		return
	}
	// FIXME: Lstat or Stat?
	// TODO: what to do with err? can we safely ignore?
	mode, err := os.Lstat(ev.Name)
	if err != nil {
		log.Println("error processing subdir:", err.Error())
		return
	}
	if !mode.IsDir() {
		return
	}

	// FIXME: handle renames
	if ev.IsCreate() {
		log.Println("add watch", ev.Name)
		// FIXME: what to do with err?
		watcher.Watch(ev.Name)
	}
}
Beispiel #7
0
func (fw *InotifyFileWatcher) ChangeEvents(t tomb.Tomb, fi os.FileInfo) *FileChanges {
	changes := NewFileChanges()

	w, err := fsnotify.NewWatcher()
	if err != nil {
		panic(err)
	}
	err = w.Watch(fw.Filename)
	if err != nil {
		panic(err)
	}

	fw.Size = fi.Size()

	go func() {
		defer w.Close()
		defer w.RemoveWatch(fw.Filename)
		defer changes.Close()

		for {
			prevSize := fw.Size

			var evt *fsnotify.FileEvent

			select {
			case evt = <-w.Event:
			case <-t.Dying():
				return
			}

			switch {
			case evt.IsDelete():
				fallthrough

			case evt.IsRename():
				changes.NotifyDeleted()
				return

			case evt.IsModify():
				fi, err := os.Stat(fw.Filename)
				if err != nil {
					// XXX: no panic here
					panic(err)
				}
				fw.Size = fi.Size()

				if prevSize > 0 && prevSize > fw.Size {
					changes.NotifyTruncated()
				} else {
					changes.NotifyModified()
				}
				prevSize = fw.Size
			}
		}
	}()

	return changes
}
Beispiel #8
0
func handleEvent(ev *fsnotify.FileEvent) {
	if len(ev.Name) > 0 {
		switch {
		case ev.IsCreate():
			handleCreate(ev.Name)
		case ev.IsDelete():
			handleDelete(ev.Name)
		case ev.IsModify():
			handleModify(ev.Name)
		}
	}
}
Beispiel #9
0
func eventDesc(ev *fsnotify.FileEvent) string {
	switch {
	case ev.IsCreate():
		return "created"
	case ev.IsDelete():
		return "removed"
	case ev.IsModify():
		return "modified"
	case ev.IsRename():
		return "renamed"
	default:
		return ""
	}
}
Beispiel #10
0
func watch() {

	var event *fsnotify.FileEvent
	var open bool

	for {
		if event, open = <-watcher.Event; open == false {
			break
		} else if event.IsModify() {
			go fileModified(event)
		} else if event.IsDelete() {
			out("DELETED", event.Name)
		} else if event.IsCreate() {
			go fileCreated(event)
		} else if event.IsRename() {
		}
	}
}
Beispiel #11
0
func (r Rule) MatchedCommand(ev *fsnotify.FileEvent) (string, bool) {
	if r.eventName == "MODIFY" && !ev.IsModify() {
		return "", false
	}
	if r.eventName == "CREATE" && !ev.IsCreate() {
		return "", false
	}
	if r.eventName == "DELETE" && !ev.IsDelete() {
		return "", false
	}
	match := r.match.FindStringSubmatch(ev.Name)
	if match == nil {
		return "", false
	}
	if len(match) == 1 {
		return r.cmd, true
	}
	return r.match.ReplaceAllString(ev.Name, r.cmd), true
}
Beispiel #12
0
func PreprocessEvent(event *fsnotify.FileEvent) {
	path := event.Name
	//ignore 5 root dir
	for _, p := range dir_list {
		if p == path {
			return
		}
	}

	if event.IsDelete() {
		ProcessDeleteEvent(event)
	} else {
		if isDir, err := pathutil.IsDir(path); isDir && err == nil {
			if event.IsCreate() {
				ProcessCreateEvent(event)
			} else if event.IsModify() {
				ProcessModifyEvent(event)
			} else if event.IsRename() {
				ProcessRenameEvent(event)
			}
		}
	}
}
Beispiel #13
0
func (fw *InotifyFileWatcher) ChangeEvents(t *tomb.Tomb, fi os.FileInfo) *FileChanges {
	changes := NewFileChanges()

	w, err := inotifyTracker.NewWatcher()
	if err != nil {
		util.Fatal("Error creating fsnotify watcher: %v", err)
	}
	err = w.Watch(fw.Filename)
	if err != nil {
		util.Fatal("Error watching %v: %v", fw.Filename, err)
	}

	fw.Size = fi.Size()

	go func() {
		defer inotifyTracker.CloseWatcher(w)

		for {
			prevSize := fw.Size

			var evt *fsnotify.FileEvent
			var ok bool

			select {
			case evt, ok = <-w.Event:
				if !ok {
					return
				}
			case <-t.Dying():
				return
			}

			switch {
			case evt.IsDelete():
				fallthrough

			case evt.IsRename():
				changes.NotifyDeleted()
				return

			case evt.IsModify():
				fi, err := os.Stat(fw.Filename)
				if err != nil {
					if os.IsNotExist(err) {
						changes.NotifyDeleted()
						return
					}
					// XXX: report this error back to the user
					util.Fatal("Failed to stat file %v: %v", fw.Filename, err)
				}
				fw.Size = fi.Size()

				if prevSize > 0 && prevSize > fw.Size {
					changes.NotifyTruncated()
				} else {
					changes.NotifyModified()
				}
				prevSize = fw.Size
			}
		}
	}()

	return changes
}
Beispiel #14
0
func (self *Launcher) itemChangedHandler(ev *fsnotify.FileEvent, name string, info map[string]ItemChangedStatus) {
	if _, ok := info[name]; !ok {
		info[name] = ItemChangedStatus{
			make(chan bool),
			make(chan bool),
			make(chan bool),
			make(chan bool),
			0,
		}
	}
	if ev.IsRename() {
		logger.Info("renamed")
		select {
		case <-info[name].renamed:
		default:
		}
		go func() {
			select {
			case <-info[name].notRenamed:
				return
			case <-time.After(time.Second):
				<-info[name].renamed
				if true {
					self.emitItemChanged(name, SoftwareStatusDeleted, info)
				}
			}
		}()
		info[name].renamed <- true
	} else if ev.IsCreate() {
		self.emitItemChanged(name, SoftwareStatusCreated, info)
		go func() {
			select {
			case <-info[name].renamed:
				// logger.Info("not renamed")
				info[name].notRenamed <- true
				info[name].renamed <- true
			default:
				// logger.Info("default")
			}
			select {
			case <-info[name].notCreated:
				return
			case <-time.After(time.Second):
				<-info[name].created
			}
		}()
		info[name].created <- true
	} else if ev.IsModify() && !ev.IsAttrib() {
		go func() {
			select {
			case <-info[name].created:
				info[name].notCreated <- true
			}
			select {
			case <-info[name].renamed:
				self.emitItemChanged(name, SoftwareStatusModified, info)
			default:
			}
		}()
	} else if ev.IsAttrib() {
		go func() {
			select {
			case <-info[name].renamed:
				<-info[name].created
				info[name].notCreated <- true
			default:
			}
		}()
	} else if ev.IsDelete() {
		if true {
			self.emitItemChanged(name, SoftwareStatusDeleted, info)
		}
	}
}
Beispiel #15
0
func goFileTouched(event *fsnotify.FileEvent) bool {
	return (event.IsModify() || event.IsRename()) && strings.HasSuffix(event.Name, ".go")
}