/
dirwatch.go
113 lines (98 loc) · 2.23 KB
/
dirwatch.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package main
import (
"code.google.com/p/go.exp/inotify"
"io/ioutil"
"log"
"path"
"strings"
)
type Dirwatch interface {
IsValid(path, dir, file string) bool
IsModified(path, dir, file string) bool
OnDelete(path, dir, file string)
OnChange(path, dir, file string)
}
type baseDirwatch struct {
Paths []string
IFlags int
watcher *inotify.Watcher
}
func (d *baseDirwatch) IsValid(path, dir, file string) bool {
log.Println("dirwatch: you should override IsValid")
return false
}
func (d *baseDirwatch) IsModified(path, dir, file string) bool {
log.Println("dirwatch: you should override IsModified")
return false
}
func (d *baseDirwatch) OnDelete(path, dir, file string) {
log.Println("dirwatch: you should override OnDelete")
}
func (d *baseDirwatch) OnChange(path, dir, file string) {
log.Println("dirwatch: you should override OnChange")
}
func isMedia(path string) bool {
switch {
case strings.HasSuffix(path, ".mp3"):
return true
case strings.HasSuffix(path, ".m4a"):
return true
case strings.HasSuffix(path, ".ogg"):
return true
case strings.HasSuffix(path, ".flac"):
return true
}
return false
}
func processDir(base, dir string, dirs, mediaFiles chan string) (err error) {
log.Printf("adding %s\n", dir)
var fullPath string
// special case the top level dir
if base == dir {
fullPath = base
dir = ""
} else {
fullPath = path.Join(base, dir)
}
info, err := ioutil.ReadDir(fullPath)
if err != nil {
return
}
for _, fi := range info {
name := fi.Name()
if fi.IsDir() {
dirs <- path.Join(dir, name)
} else if isMedia(name) {
mediaFiles <- path.Join(dir, name)
}
}
return
}
func initWatch(base string, dirs, mediaFiles chan string) (err error) {
outer:
for {
select {
case dir := <-dirs:
if err = processDir(base, dir, dirs, mediaFiles); err != nil {
return
}
default:
break outer
}
}
return nil
}
func NewDirwatch(path string) (result Dirwatch, err error) {
d := new(baseDirwatch)
if d.watcher, err = inotify.NewWatcher(); err != nil {
return
}
mediaFiles := make(chan string, 10240)
dirs := make(chan string, 1024)
dirs <- path
if err = initWatch(path, dirs, mediaFiles); err != nil {
return
}
log.Printf("len files: %d\n", len(mediaFiles))
return d, nil
}